Skip to content

Implement multi-controlled U1 as gate#3883

Merged
mergify[bot] merged 28 commits into
Qiskit:masterfrom
Cryoris:implement-mcu1-gate
Apr 2, 2020
Merged

Implement multi-controlled U1 as gate#3883
mergify[bot] merged 28 commits into
Qiskit:masterfrom
Cryoris:implement-mcu1-gate

Conversation

@Cryoris
Copy link
Copy Markdown
Collaborator

@Cryoris Cryoris commented Feb 24, 2020

Summary

The multi-controlled U1 gate is currently implemented as function only, not as class. This PR integrates the functionality in a class.

Details and comments

The tests for mcu1 are already being migrated in #3714, therefore this PR doesn't include any.

Open questions:

  • Should the multi-controlled and singly-controlled gate be merged to have CU1(theta, num_control_qubits=1)?
  • The previous _apply_mcu1 function had a global phase argument, which was not accessible via the QuantumCircuit.mcu1 method. With the global phase PR being a work in progress I kept the functionality in the class to easily add it later on. Is that fine?
  • There's unfortunately no reference to where this algorithm comes from in the original code. I'll try to find one, or does anyone by chance know where this comes from?
    Edit: This is actually explained in Nielsen & Chuang.

Cryoris and others added 2 commits February 24, 2020 15:17
this gate has been implemented in Aqua before, see
https://github.com/Qiskit/qiskit-aqua/blame/769ca8d/qiskit/aqua/circuits/gates/multi_control_u1_gate.py
The contributors have been added as co-authors.

Co-authored-by: Albert Frisch <alfr@de.ibm.com>
Co-authored-by: Shaohan Hu <shaohan.hu@ibm.com>
Co-authored-by: Manoel Marques <manoel@us.ibm.com>
@Cryoris Cryoris changed the title [WIP] Implement mcu1 as gate [WIP] Implement multi-controlled U1 as gate Feb 25, 2020
Comment thread qiskit/extensions/standard/u1.py Outdated
Comment thread test/python/circuit/test_controlled_gate.py Outdated
Comment thread test/python/circuit/test_controlled_gate.py Outdated
Comment thread test/python/circuit/test_controlled_gate.py Outdated
Comment thread qiskit/extensions/standard/u1.py Outdated
Comment thread qiskit/extensions/standard/u1.py Outdated
- implement review changes by @AJAVADI
- Some tests started failing which should not have been affected by the changes in this PR.
Looking at the code, these tests should fail since they require a ancilla qubits, which are None.
I'm not sure why these tests have been skipped before.
Comment thread qiskit/circuit/add_control.py Outdated
Comment thread qiskit/extensions/standard/u1.py Outdated
Cryoris added 5 commits March 4, 2020 12:30
- add ctrl state to matrix computation of MCU1
- revert to not specifying noancilla mode in mcry/mct
- handle test cases for MCU1 in the same fashion as MSGate/Barrier
@Cryoris Cryoris requested review from ajavadia and ewinston March 24, 2020 23:17
Comment thread qiskit/extensions/standard/u1.py Outdated
Cryoris added 2 commits March 25, 2020 15:54
the same logic is also used for the MCU3 gate, therefore it's exported to another function in u3.py
Comment thread qiskit/extensions/standard/u1.py Outdated
Comment thread qiskit/extensions/standard/u1.py Outdated
Comment thread test/python/circuit/test_gate_definitions.py Outdated
Comment thread qiskit/circuit/add_control.py
Comment thread qiskit/extensions/standard/u1.py Outdated
Comment thread qiskit/extensions/standard/u3.py Outdated
@Cryoris Cryoris changed the title [WIP] Implement multi-controlled U1 as gate Implement multi-controlled U1 as gate Mar 27, 2020
@Cryoris Cryoris added this to the 0.13 milestone Mar 27, 2020
Copy link
Copy Markdown
Member

@ajavadia ajavadia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good, just concerned about lumping CU1 and MCU1.

Also can you show what a CU1 and CCU1 gate will look like in the drawer?
They should be symmetric (i.e. changing controls/target doesn't change the gate).

Comment thread qiskit/extensions/standard/u1.py Outdated
Comment thread qiskit/extensions/standard/u1.py Outdated
"""The controlled-u1 gate."""

def __init__(self, theta):
def __init__(self, theta, num_ctrl_qubits=1):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, a CU1Gate should really just mean 1 control. I think a MCU1 is a more appropriate name for more controls (similar to mcrx, mcry, etc. that we have).

Separating them gives you the flexibility to write algorithms for synthesis of multi-control gates (which are non-trivial), whereas for CU1 it's already a 2-qubit gate and is easier to decompose (requires no ancilla, routing, etc.).

I know that ultimately one is the generalization of the other, but it's more about separating out common cases. By this logic we could lump together X, CX, CCX, and MCT (which I think should be called MCX btw). Each has the same base gate, with 0, 1, 2, 3+ controls respectively. But we don't do that since X, CX and CCX are extensively studied and are common.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, agreed, also if we find different ways to synthesize the MCU1 it makes sense to separate this logic from CU1 and have different types derived from MCU1.
@ewinston Do you agree to change this?

@Cryoris Cryoris requested review from ajavadia and ewinston April 2, 2020 11:57
Comment on lines +266 to +273
q_0: ────■────
.
q_(n-1): ────■────
┌───┴───┐
q_n: ┤ U1(λ) ├
└───────┘
Copy link
Copy Markdown
Member

@ajavadia ajavadia Apr 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how this actually gets rendered currently? It should be something like:

            q_0: ────■────
                     │ 
                     .
                     │         λ
        q_(n-1): ────■────
                     .
                     │
        q_(n):   ────■────

Because in this gate changing control and target will not make a difference. I know the drawer is currently correct with one control, but maybe not for more controls. If not, then can you open an issue? (It should b e fixed for all 3 types of drawer: latex, text, mpl)

@mergify mergify Bot merged commit dbc4621 into Qiskit:master Apr 2, 2020
@kdk kdk added the Changelog: Changed Add a "Changed" entry in the GitHub Release changelog. label Apr 9, 2020
faisaldebouni pushed a commit to faisaldebouni/qiskit-terra that referenced this pull request Aug 5, 2020
* port mcu1 from function to gate

this gate has been implemented in Aqua before, see
https://github.com/Qiskit/qiskit-aqua/blame/769ca8d/qiskit/aqua/circuits/gates/multi_control_u1_gate.py
The contributors have been added as co-authors.

Co-authored-by: Albert Frisch <alfr@de.ibm.com>
Co-authored-by: Shaohan Hu <shaohan.hu@ibm.com>
Co-authored-by: Manoel Marques <manoel@us.ibm.com>

* update init, remove old implementation

* fix tests

* fix cyclic import by full path

* make `control` use MCU1

* mcu1 already importet via u1.py

* implement review changes and fix tests

- implement review changes by @AJAVADI
- Some tests started failing which should not have been affected by the changes in this PR.
Looking at the code, these tests should fail since they require a ancilla qubits, which are None.
I'm not sure why these tests have been skipped before.

* apply changes of the review

- add ctrl state to matrix computation of MCU1
- revert to not specifying noancilla mode in mcry/mct
- handle test cases for MCU1 in the same fashion as MSGate/Barrier

* move MCU1 into CU1

* try to fix docstring error?

* move gray code logic to external function

the same logic is also used for the MCU3 gate, therefore it's exported to another function in u3.py

* circumvent special case distinction for CU1Gate

* keep mode 'noancilla'

* move generate gray code to u3

multi_controlled_rotation_gates will be removed in a fututre PR

* move determination of num free params to utils

* revert to MCU1 as own class

Co-authored-by: Albert Frisch <alfr@de.ibm.com>
Co-authored-by: Shaohan Hu <shaohan.hu@ibm.com>
Co-authored-by: Manoel Marques <manoel@us.ibm.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changelog: Changed Add a "Changed" entry in the GitHub Release changelog.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants